// index.js
const app = getApp()
const CryptoJS = require('crypto-js')

Page({
  data: {
    messages: [],
    inputText: '',
    speaking: false,
    personality: {
      name: '征兵小助手',
      role: '智能助手',
    },
    isProcessing: false,
    showVoiceInput: false,
    hasRecordAuth: false,
    isRecording: false
  },

  onLoad() {
    this.initVoice()
    this.checkRecordPermission()
    this.addMessage('ai', '你好！我是你的征兵小助手！我可以帮助你解答关于大学与入伍有关的各类问题。如果你有什么需要，随时告诉我！')
  },

  initVoice() {
    this.recorderManager = wx.getRecorderManager()
    this.innerAudioContext = wx.createInnerAudioContext()
    
    this.recorderManager.onStart(() => {
      console.log('录音开始')
      this.setData({ speaking: true })
    })
    
    this.recorderManager.onStop(async (res) => {
      console.log('录音结束')
      this.setData({ speaking: false })
      
      try {
        wx.showLoading({ title: '识别中...' })
        const result = await this.speechToText(res.tempFilePath)
        
        if (result && result.text) {
          const currentText = this.data.inputText
          const newText = currentText 
            ? `${currentText}，${result.text}`
            : result.text
          
          this.setData({ inputText: newText })
        }
      } catch (error) {
        console.error('语音识别失败：', error)
        wx.showToast({ title: '语音识别失败', icon: 'none' })
      } finally {
        wx.hideLoading()
      }
    })

    this.recorderManager.onError((err) => {
      console.error('录音错误：', err)
      this.setData({ speaking: false })
      wx.showToast({
        title: '录音出错',
        icon: 'none'
      })
    })
  },

  async speechToText(audioPath) {
    try {
      const APPID = 'aa5795c2'
      const APISecret = 'ZDFiM2JhMWQ1YzBiMzYwOGE1ODMzNjg4'
      const APIKey = 'f67e695bd64d83ecdacdc5e9411951c9'
      const url = 'wss://iat-api.xfyun.cn/v2/iat'
      
      const fileContent = wx.getFileSystemManager().readFileSync(audioPath, 'base64')
      const currentTime = new Date().toGMTString()
      const signatureOrigin = `host: iat-api.xfyun.cn\ndate: ${currentTime}\nGET /v2/iat HTTP/1.1`
      const signatureSha = CryptoJS.HmacSHA256(signatureOrigin, APISecret)
      const signature = CryptoJS.enc.Base64.stringify(signatureSha)
      const authorizationOrigin = `api_key="${APIKey}",algorithm="hmac-sha256",headers="host date request-line",signature="${signature}"`
      const authorization = CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(authorizationOrigin))

      return new Promise((resolve, reject) => {
        const socketTask = wx.connectSocket({
          url: `${url}?authorization=${encodeURIComponent(authorization)}&date=${encodeURIComponent(currentTime)}&host=iat-api.xfyun.cn`,
          header: {
            'Content-Type': 'application/json'
          }
        })

        let resultText = ''

        socketTask.onOpen(() => {
          console.log('WebSocket连接已打开')
          
          const businessParams = {
            common: {
              app_id: APPID
            },
            business: {
              language: 'zh_cn',
              domain: 'iat',
              accent: 'mandarin',
              dwa: 'wpgs',
              pd: 'edu',
              ptt: 0,
              rlang: 'zh-cn',
              vinfo: 1,
              vad_eos: 3000,
              sample_rate: '16000'
            },
            data: {
              status: 0,
              format: 'audio/L16;rate=16000',
              encoding: 'raw',
              audio: fileContent
            }
          }
          
          socketTask.send({
            data: JSON.stringify(businessParams),
            success: () => {
              console.log('数据发送成功')
              socketTask.send({
                data: JSON.stringify({
                  data: {
                    status: 2,
                    audio: ''
                  }
                })
              })
            }
          })
        })

        socketTask.onMessage((res) => {
          try {
            const data = JSON.parse(res.data)
            if (data.code === 0 && data.data && data.data.result) {
              data.data.result.ws.forEach(ws => {
                ws.cw.forEach(cw => {
                  resultText += cw.w
                })
              })
              
              if (data.data.status === 2) {
                socketTask.close()
                resolve({ text: resultText })
              }
            } else {
              reject(new Error(data.message || '语音识别失败'))
            }
          } catch (error) {
            console.error('解析响应数据失败:', error)
            reject(error)
          }
        })

        socketTask.onError((err) => {
          console.error('WebSocket错误:', err)
          reject(err)
        })

        socketTask.onClose(() => {
          console.log('WebSocket已关闭')
        })
      })
    } catch (error) {
      console.error('语音识别错误:', error)
      throw error
    }
  },

  addMessage(type, content) {
    const messages = [...this.data.messages, { type, content }]
    this.setData({ messages })
    this.scrollToBottom()
  },

  scrollToBottom() {
    wx.nextTick(() => {
      wx.createSelectorQuery()
        .select('.messages-container')
        .node()
        .exec(res => {
          if (res[0]) {
            res[0].node.scrollTo({
              top: res[0].node.scrollHeight,
              behavior: 'smooth'
            })
          }
        })
    })
  },

  async getAIResponse(text) {
    try {
      if (this.data.isProcessing) {
        wx.showToast({
          title: '请等待上一个回答完成',
          icon: 'none'
        })
        return
      }

      this.setData({ isProcessing: true })
      
      // 先添加一个空的 AI 消息
      const messageIndex = this.data.messages.length
      this.addMessage('ai', '')
      
      // 用于存储完整的响应文本
      let fullResponse = ''
      let isTyping = false
      
      const typeText = (text) => {
        return new Promise((resolve) => {
          const chars = text.split('')
          let currentIndex = 0
          
          const typeChar = () => {
            if (currentIndex < chars.length) {
              const messages = this.data.messages
              messages[messageIndex].content = fullResponse + chars.slice(0, currentIndex + 1).join('')
              this.setData({ messages })
              this.scrollToBottom()
              
              currentIndex++
              setTimeout(typeChar, 50)
            } else {
              fullResponse += text
              resolve()
            }
          }
          
          typeChar()
        })
      }

      const response = await this.streamCallSparkAPI('chat', text, async (chunk) => {
        // 等待前一段文字打字完成
        while (isTyping) {
          await new Promise(resolve => setTimeout(resolve, 50))
        }
        isTyping = true
        await typeText(chunk)
        isTyping = false
      })
      
    } catch (error) {
      console.error('AI响应错误:', error)
      wx.showToast({ 
        title: error.message || '获取回复失败', 
        icon: 'none',
        duration: 2000
      })
    } finally {
      this.setData({ isProcessing: false })
    }
  },

  async textToSpeech(text) {
    try {
      const response = await this.callSparkAPI('tts', text)
      if (response.audio) {
        const audioUrl = `data:audio/mp3;base64,${response.audio}`
        this.innerAudioContext.src = audioUrl
        this.innerAudioContext.play()
        this.setData({ speaking: true })
        
        this.innerAudioContext.onEnded(() => {
          this.setData({ speaking: false })
        })
      }
    } catch (error) {
      console.error('语音合成错误:', error)
    }
  },

  async callSparkAPI(type, content) {
    // API配置
    const APIKey = "f67e695bd64d83ecdacdc5e9411951c9"
    const APISecret = "ZDFiM2JhMWQ1YzBiMzYwOGE1ODMzNjg4"
    const url = 'https://spark-api-open.xf-yun.com/v1/chat/completions'

    try {
      const res = await new Promise((resolve, reject) => {
        wx.request({
          url,
          method: 'POST',
          header: {
            'Content-Type': 'application/json',
            'Authorization': `Bearer ${APIKey}:${APISecret}`
          },
          data: {
            model: "generalv3.5",  // 使用 Spark 4.0 Ultra 模型
            messages: [
              {
                role: "system",
                content: "你是一个征兵智能助手，名叫征兵小助手，你的职责是帮助学生解答征兵相关的问题。"
              },
              {
                role: "user",
                content: content
              }
            ],
            // 4.0 Ultra 特有的参数配置
            temperature: 0.7,
            top_k: 4,
            max_tokens: 3000,  // 4.0 Ultra 支持更长的输出
            stream: true,
            user: "user_" + Date.now().toString(),
            // 开启搜索功能
            tools: [
              {
                type: "web_search",
                web_search: {
                  enable: true,
                  show_ref_label: true
                }
              }
            ]
          },
          success: (res) => {
            console.log('API完整响应:', res)
            if (res.statusCode === 200) {
              if (res.data.choices && res.data.choices.length > 0) {
                resolve({ content: res.data.choices[0].message.content })
              } else {
                reject(new Error('无效的响应内容'))
              }
            } else {
              console.error('API错误响应:', res)
              let errorMsg = '请求失败'
              if (res.data.error) {
                errorMsg = res.data.error.message || '服务异常'
              }
              reject(new Error(errorMsg))
            }
          },
          fail: (err) => {
            console.error('请求失败:', err)
            reject(new Error('网络请求失败'))
          }
        })
      })

      return res

    } catch (error) {
      console.error('API调用错误:', error)
      throw error
    }
  },

  onInput(e) {
    this.setData({ inputText: e.detail.value })
  },

  sendMessage() {
    const { inputText } = this.data
    if (!inputText.trim()) return
    
    this.addMessage('user', inputText)
    this.getAIResponse(inputText)
    this.setData({ inputText: '' })
  },

  toggleVoiceInput() {
    if (!this.data.showVoiceInput) {
      this.checkRecordPermission()
    }
    this.setData({
      showVoiceInput: !this.data.showVoiceInput
    })
  },

  async checkRecordPermission() {
    try {
      const { authSetting } = await wx.getSetting()
      if (authSetting['scope.record'] === undefined) {
        await wx.authorize({ scope: 'scope.record' })
        this.setData({ hasRecordAuth: true })
      } else if (!authSetting['scope.record']) {
        wx.showModal({
          title: '需要录音权限',
          content: '请授权小程序使用录音功能',
          success: (res) => {
            if (res.confirm) {
              wx.openSetting({
                success: (res) => {
                  this.setData({ hasRecordAuth: res.authSetting['scope.record'] })
                }
              })
            }
          }
        })
      } else {
        this.setData({ hasRecordAuth: true })
      }
    } catch (error) {
      console.error('获取录音权限失败：', error)
      wx.showToast({
        title: '无法使用录音功能',
        icon: 'none'
      })
    }
  },

  startRecord() {
    if (!this.data.hasRecordAuth) {
      this.checkRecordPermission()
      return
    }

    try {
      this.recorderManager.start({
        duration: 60000,
        sampleRate: 16000,
        numberOfChannels: 1,
        encodeBitRate: 96000,
        format: 'PCM',
        frameSize: 0.5
      })
    } catch (error) {
      console.error('开始录音失败：', error)
      wx.showToast({
        title: '录音启动失败',
        icon: 'none'
      })
    }
  },

  stopRecord() {
    try {
      this.recorderManager.stop()
    } catch (error) {
      console.error('停止录音失败：', error)
      this.setData({ speaking: false })
      wx.showToast({
        title: '录音停止失败',
        icon: 'none'
      })
    }
  },

  async streamCallSparkAPI(type, content, onChunk) {
    const APIKey = "gLioFNMJOzuEjSqvxymL"
    const APISecret = "rjcuGEaqjNiLJZzBLtlY"
    const url = 'https://spark-api-open.xf-yun.com/v1/chat/completions'

    try {
      const res = await new Promise((resolve, reject) => {
        wx.request({
          url,
          method: 'POST',
          header: {
            'Content-Type': 'application/json',
            'Authorization': `Bearer ${APIKey}:${APISecret}`,
            'Accept': 'text/event-stream'
          },
          data: {
            model: "4.0Ultra",
            messages: [
              {
                role: "system",
                content: "你是一个智能助手，名叫征兵小助手，你的职责是帮助学生解答与征兵相关的问题。"
              },
              {
                role: "user",
                content: content
              }
            ],
            temperature: 0.7,
            top_k: 4,
            max_tokens: 8192,
            stream: true,
            user: "user_" + Date.now().toString(),
            tools: [
              {
                type: "web_search",
                web_search: {
                  enable: true,
                  show_ref_label: true
                }
              }
            ]
          },
          responseType: 'text',
          success: (res) => {
            if (res.statusCode === 200) {
              let fullContent = ''
              
              // 处理返回的数据
              const processChunk = (text) => {
                if (!text || text.trim() === '') return
                try {
                  const jsonStr = text.replace(/^data: /, '').trim()
                  if (jsonStr === '[DONE]') return

                  const data = JSON.parse(jsonStr)
                  if (data.choices && data.choices[0].delta && data.choices[0].delta.content) {
                    const chunk = data.choices[0].delta.content
                    fullContent += chunk
                    onChunk(chunk)
                  }
                } catch (e) {
                  console.error('解析数据块错误:', e, text)
                }
              }

              // 按行分割并处理每一行
              const chunks = res.data.split('\n')
              for (let i = 0; i < chunks.length; i++) {
                const chunk = chunks[i].trim()
                if (chunk) {
                  processChunk(chunk)
                }
              }

              resolve({ content: fullContent })
            } else {
              console.error('API错误响应:', res)
              reject(new Error(res.data.error?.message || '请求失败'))
            }
          },
          fail: (err) => {
            console.error('请求失败:', err)
            reject(new Error('网络请求失败'))
          }
        })
      })

      return res

    } catch (error) {
      console.error('API调用错误:', error)
      throw error
    }
  }
})
